<template>
  <basic-container>
    <el-tabs type="border-card" class="tab-font">
      <el-tab-pane label="生产平衡率报表搜索"> </el-tab-pane>
      <avue-form ref="form" :option="option" v-model="form">
        <template slot="btn">
          <el-button type="primary" size="small" class="el-icon-search" @click="handleSubmit">搜索</el-button>
          <el-button size="small" class="el-icon-delete" @click="handleCancel">清空</el-button>
        </template>
      </avue-form>
    </el-tabs>
    <el-tabs type="border-card" class="chart-tab tab-font">
      <el-tab-pane label="生产平衡率报表明细"> </el-tab-pane>
      <el-row :gutter="20">
        <el-col :span="24">
          <chart-view class="chart-content" :chart-option="chartOption" :auto-resize="true" width="100%" height="450px" />
          <avue-crud :option="tableOption" :table-loading="loading" :data="data" :page.sync="tablePage" @current-change="currentChange" @size-change="sizeChange" ref="crud">
            <template slot="menu" slot-scope="{ type, size, row, index }">
              <el-button icon="el-icon-view" :size="size" type="text" @click="handleViewDetail(row)">详情</el-button>
            </template>
            <template slot="menuLeft">
              <el-button type="warning" size="small" plain icon="el-icon-download" @click="handleExport" :loading="exportBtnLoading">导出 </el-button>
            </template>
          </avue-crud>
        </el-col>
      </el-row>
    </el-tabs>
    <el-dialog title="各工序平均CT时间" append-to-body :visible.sync="dialogVisible" width="35%" :destroy-on-close="true">
      <avue-crud :option="detailTableOption" :data="detailData" ref="crud"> </avue-crud>
    </el-dialog>
  </basic-container>
</template>

<script>
import ChartView from '@/components/chart/index.vue';
import moment from 'moment';
import { tableOption, option, detailTableOption } from '@/views/report/productionBalanceRateOption.js';
import 'echarts/lib/component/dataZoom';
import {
  exportBalanceReportChartData,
  exportChangeLineReportData,
  getBalanceReportChartData,
  getBalanceReportData,
  getChangeLineReportChartData,
  getChangeLineReportData
} from '@/api/report/report';
export default {
  name: 'productionBalanceRate',
  components: {
    ChartView
  },
  data() {
    return {
      tableOption,
      option,
      loading: false,
      dialogVisible: false,
      detailData: [],
      detailTableOption,
      exportBtnLoading: false,
      data: [],
      form: {
        examineDate: this.getDefaultTime()
      },
      tablePage: {
        pageSize: 20,
        currentPage: 1,
        total: 0
      },
      chartOption: {
        grid: {
          bottom: '30%'
        },
        xAxis: {
          type: 'category',
          name: '工单号/日期',
          data: [],
          nameTextStyle: {
            padding: [60, 0, 0, 0]
          }
        },
        yAxis: {
          type: 'value',
          name: '生产平衡率（%）'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter: (params) => {
            let tooltipHtml = '<div class="custom-tooltip">';
            for (let i = 0; i < params.length; i++) {
              if (params[i].value !== 0) {
                tooltipHtml += '<div class="tooltip-title">' + '<li>' + '工单' + params[i].name + '生产平衡率为' + ' : ' + params[i].value + '%';
              }
            }
            tooltipHtml += '<ul class="tooltip-list">';
            tooltipHtml += '</li></div></ul></div>';
            return tooltipHtml;
          }
        },
        series: [],
        dataZoom: [
          {
            type: 'slider',
            xAxisIndex: 0,
            start: 0,
            end: 100
          }
        ]
      }
    };
  },
  methods: {
    async onLoad(isDrawChart = true) {
      const params = this.getQueryParameter(true);
      try {
        this.loading = true;
        const res = await getBalanceReportData(params);
        const data = res.data.data;
        this.data = data.records;
        this.tablePage = {
          total: data.total,
          pageSize: data.size,
          currentPage: data.current
        };
        if (isDrawChart) {
          await this.setChartOption();
        }
      } catch (e) {
      } finally {
        this.loading = false;
      }
    },
    currentChange(currentPage) {
      this.tablePage.currentPage = currentPage;
      this.onLoad(false);
    },
    sizeChange(pageSize) {
      this.tablePage.pageSize = pageSize;
      this.onLoad(false);
    },
    handleExport() {
      this.$refs.form.validate(async (valid, done) => {
        if (valid) {
          const params = this.getQueryParameter(false);
          try {
            this.exportBtnLoading = true;
            const res = await exportBalanceReportChartData(params);
            const blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=UTF-8' });
            const fileName = `生产平衡率报表.xlsx`;
            const link = document.createElement('a');
            link.download = fileName;
            link.style.display = 'none';
            link.href = URL.createObjectURL(blob);
            document.body.append(link);
            link.click();
            URL.revokeObjectURL(link.href);
            document.body.removeChild(link);
          } catch (e) {
            console.log(e);
            this.$message.error('系统错误，请联系管理员');
          } finally {
            this.exportBtnLoading = false;
          }
          done();
        }
      });
    },
    handleSubmit(form, done) {
      this.$refs.form.validate((valid, done) => {
        if (valid) {
          this.onLoad(true);
          done();
        }
      });
    },
    handleCancel() {
      this.tablePage.currentPage = 1;
      this.tablePage.total = 0;
      this.$refs.form.resetForm();
      this.queryParams = {};
      this.$set(this.chartOption, 'series', []);
    },
    getDefaultTime() {
      const startTime = this.$moment(new Date()).subtract(7, 'days').format('yyyy-MM-DD');
      const endTime = this.$moment(new Date()).format('yyyy-MM-DD');
      return [startTime, endTime];
    },
    handleViewDetail(row) {
      this.detailData = JSON.parse(row.ctDetail);
      this.dialogVisible = true;
    },
    getQueryParameter(isNeedPage) {
      const { examineDate, partNo } = this.form;
      const { currentPage, pageSize } = this.tablePage;
      const startDate = this.$moment(new Date(examineDate[0])).format('YYYY-MM-DD');
      const endDate = this.$moment(new Date(examineDate[1])).format('YYYY-MM-DD');
      return isNeedPage
        ? {
            partNo,
            startDate,
            endDate,
            size: pageSize,
            current: currentPage
          }
        : {
            partNo,
            startDate,
            endDate
          };
    },
    async getChartData() {
      const params = this.getQueryParameter(false);
      try {
        const res = await getBalanceReportChartData(params);
        const data = res.data.data;
        data.sort((a, b) => {
          return new Date(a.windowTime) - new Date(b.windowTime);
        });
        return data;
      } catch (e) {
        console.warn(e);
      }
    },
    async setChartOption() {
      // 获取数据
      const data = await this.getChartData();
      //产品b->产品a 随机生成颜色,并且同种’产品b->产品a‘为同种颜色
      const colorMap = this.getProductionColor(data);
      const cloneData = this._cloneDeep(data);
      const xAxis = this.getXAxis(cloneData);
      const chartData = this.getChartOptionData(cloneData, colorMap);
      const series = this.getSeries(this._cloneDeep(chartData));
      const zoom = this.getZoom(data);
      this.$set(this.chartOption, 'xAxis', xAxis);
      this.$set(this.chartOption, 'series', series);
      this.$set(this.chartOption, 'dataZoom', zoom);
    },
    getProductionColor(data) {
      const colorMap = {};
      data.forEach((el) => {
        if (!(el.workOrderNo in colorMap)) {
          colorMap[el.workOrderNo] = this.getRandomColor();
        }
      });
      return colorMap;
    },
    // 生成随机颜色的方法
    getRandomColor() {
      const letters = '0123456789ABCDEF';
      let color = '#';
      for (let i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
      }
      return color;
    },
    // 获取xAxis
    getXAxis(data) {
      return {
        type: 'category',
        data: Array.from(new Set(data.map((item) => item.windowTime))),
        axisLabel: {
          interval: 0,
          margin: 60
        }
      };
    },
    getChartOptionData(chartData, colorMap = {}) {
      const longestLength = this.getLongestLength(chartData);
      const xAxisData = Array.from(new Set(chartData.map((item) => item.windowTime)));
      const deepLength = xAxisData.length || 0;
      const recordId = [];
      const arr = new Array(longestLength).fill(0);
      for (let i = 0; i < longestLength; i++) {
        // 2
        const dataItem = new Array(deepLength).fill(0);
        for (let j = 0; j < deepLength; j++) {
          // 3
          for (let k = 0; k < chartData.length; k++) {
            const item = chartData[k];
            if (!recordId.includes(item.id) && xAxisData[j] === chartData[k].windowTime) {
              dataItem[j] = {
                value: item.balancingRate,
                name: item.workOrderNo || '',
                itemStyle: {
                  opacity: Number(item.balancingRate) > 0 ? 1 : 0,
                  color: colorMap[item.workOrderNo]
                },
                label: {
                  show: true,
                  rotate: -20,
                  distance: 40,
                  offset: [40, -30] //表示文字在[横向上偏移 30，纵向上偏移 40]
                }
              };
              recordId.push(item.id);
              break;
            }
          }
        }
        arr[i] = this._cloneDeep(dataItem);
      }

      return arr;
    },
    // 获取series
    getSeries(chartData) {
      chartData.forEach((item) => {
        if (item.length) {
          item.forEach((el) => {
            if (el === 0) {
              el = {
                value: 0,
                name: '',
                itemStyle: {
                  opacity: 0,
                  color: this.getProductionColor(chartData)[item.workOrderNo]
                }
              };
            }
          });
        }
      });
      return chartData.map((item) => {
        return {
          name: 'Series 1',
          barMinWidth: 40,
          barMaxWidth: 41,
          type: 'bar',
          label: {
            show: true,
            position: 'bottom',
            formatter: (params) => {
              return params.data ? params.data.name : '';
            }
          },
          tooltip: {
            formatter: (params) => {
              return 'AA';
            }
          },
          data: item
        };
      });
    },
    // 找出 windowTime 相同的最长子项的长度
    getLongestLength(data) {
      const longestLength = data.reduce((acc, cur) => {
        const curLength = data.filter((item) => item.windowTime === cur.windowTime).length;
        if (curLength > acc) {
          return curLength;
        }
        return acc;
      }, 0);
      return longestLength;
    },
    // 获取zoom
    getZoom(data) {
      const SHOW_DATA_LENGTH = 7;
      const length = data.length;
      const zoomLength = Math.floor((7 * 100) / length);
      return [
        {
          type: 'inside',
          xAxisIndex: 0,
          start: 0,
          end: length === 0 ? 100 : zoomLength,
          minSpan: length === 0 ? 100 : zoomLength,
          bottom: 20
        },
        {
          type: 'slider',
          xAxisIndex: 0,
          start: 0,
          end: length === 0 ? 100 : zoomLength,
          minSpan: length === 0 ? 100 : zoomLength,
          bottom: 20
        }
      ];
    }
  }
};
</script>

<style scoped lang="scss">
.chart-tab {
  margin-top: 24px;
  height: calc(100vh - 350px);
  overflow-y: scroll;
}

.tab-font {
  ::v-deep .el-tabs__item {
    color: #606266 !important;
    font-weight: bold;
  }
}
</style>
